﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using UnityEngine.Serialization;
#if URP
using UnityEngine.Rendering.Universal;
#endif

public abstract class PanelCommon : MonoBehaviour {

    static Camera s_UICam;
    public static Camera uiCamera
    {
        get
        {
            if (s_UICam == null)
                s_UICam = NewDefaultUICam();
            
            return s_UICam;
        }
        set { s_UICam = value; }
    }
    static Camera s_UIFXCam;
    public static Camera uiFXCamera
    {
        get
        {
            if (s_UIFXCam == null)
                s_UIFXCam = NewDefaultUIFXCam();
            
            return s_UIFXCam;
        }
        set { s_UIFXCam = value; }
    }
    
    public Camera secondLayerUICam;

    protected Canvas m_UICanvas;

    /// <summary>
    /// 第二层UI
    /// </summary>
    protected Canvas m_SecondUICanvas;

    public static int defaultUIWidth => 1080;// Screen.width;
    public static int defaultUIHeight => 1920;// Screen.height;
    
    public const int uiCameraLayer = 5;
    public const int uiFXCameraLayer = 6;
    public const int secondUICameraLayer = 7;
    
    /// <summary>
    /// 是否显示黑色背景
    /// </summary>
    [FormerlySerializedAs("showBlack")] public bool showBackground = false;
    [FormerlySerializedAs("blackAlpha")] public float backgroundAlpha = 0.75f;

    [FormerlySerializedAs("fadeInTime")] public float showAnimTime = 0.2f;
    [FormerlySerializedAs("fadeOutTime")] public float hideAnimTime = 0.4f;

    /// <summary>
    /// 是否采用默认的Alpha淡入淡出动画
    /// </summary>
    [FormerlySerializedAs("UseDefaultFadeInAnim")] public bool showDefaultFadeIn = true;

    [FormerlySerializedAs("fadeInCurve")] public AnimationCurve showAnimCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);
    [FormerlySerializedAs("fadeOutCurve")] public AnimationCurve hideAnimCurve = AnimationCurve.EaseInOut(0, 0, 1, 1);

    /// <summary>
    /// 第二层UI，在特效之上
    /// </summary>
    [FormerlySerializedAs("SecondLayerUI")] public UnityEngine.GameObject uiSecondLayer;

    protected ZUIAnimTools MZuiAnimTools;

    [SerializeField]
    int m_layer = 0;
    public int layer
    {
        get { return m_layer; }
        set {
            m_layer = value;
            if (m_UICanvas)
                m_UICanvas.sortingOrder = m_layer;
        }
    }

    // Use this for initialization
    public virtual void Awake()
    {
        if (MZuiAnimTools == null) MZuiAnimTools = GetComponent<ZUIAnimTools>();
        if (MZuiAnimTools == null) MZuiAnimTools = gameObject.AddComponent<ZUIAnimTools>();

        m_UICanvas = gameObject.GetComponent<Canvas>();
        if (m_UICanvas == null)
            m_UICanvas = gameObject.AddComponent<Canvas>();

        InitUICanvas(m_UICanvas,uiCamera, defaultUIWidth, defaultUIHeight);

        if(this.uiSecondLayer != null)
        {
            //有第二层UI则将其移到第二层的Canvas中
            secondLayerUICam = NewUICamera(defaultUIWidth, defaultUIHeight, secondUICameraLayer, 1 << LayerMask.NameToLayer("UI"), "SecondLayerUICamera");

            UnityEngine.GameObject second = new UnityEngine.GameObject("SecondLayer");
            
            m_SecondUICanvas = second.gameObject.AddComponent<Canvas>();
            InitUICanvas(m_SecondUICanvas, secondLayerUICam, defaultUIWidth, defaultUIHeight);
            m_SecondUICanvas.sortingOrder = 99;

            uiSecondLayer.transform.SetParent(m_SecondUICanvas.transform);
            SetUIStretchAll(uiSecondLayer.GetComponent<RectTransform>());
            uiSecondLayer.transform.localScale = Vector3.one;
        }
        
        if (showBackground)
        {
            m_BlackBG = CreateBackground();
        }
    }

    public virtual void Start()
    {
        if (showDefaultFadeIn)
        {
            var rectTransform = GetComponent<RectTransform>();
            ZUIAnimTools.GetImgTxtAlpha(rectTransform, out m_ImgAlphas, out m_TextAlphas, out m_RawImgAlphas,out m_TmptxtAlphas);
            PlayShowAnim();
        }

        Transform secondLayerParent = transform.parent;
        if (m_Controller)
        {
            secondLayerParent = m_Controller.transform;
        }
        if (secondLayerUICam)
            secondLayerUICam.transform.SetParent(secondLayerParent);
        
        if (m_SecondUICanvas)
            m_SecondUICanvas.transform.SetParent(secondLayerParent);

        DoActionDelay.DelayAction(showAnimTime, () => { showAnimEnded = true; });
    }

    protected List<float> m_ImgAlphas;
    protected List<float> m_TextAlphas;
    protected List<float> m_RawImgAlphas;
    protected List<float> m_TmptxtAlphas;
    public virtual void PlayShowAnim()
    {
        var rectTransform = GetComponent<RectTransform>();

        MZuiAnimTools.InitCurve(showAnimCurve);
        MZuiAnimTools.SetImgTxtAlpha(rectTransform, 0);
        MZuiAnimTools.UIAlpha(rectTransform, m_ImgAlphas, m_TextAlphas, m_RawImgAlphas, m_TmptxtAlphas,showAnimTime, () =>
        {
            OnShowAnimEnd();
        }, ZUIAnimTools.EaseType.Curve);
        
        var cg = gameObject.GetComponent<CanvasGroup>();
        if(cg)
            cg.interactable = true;
    }

    //public bool blockInteractOnBeginHide = true;
    public virtual void PlayHideAnim()
    {
        if (this != null && GetComponent<RectTransform>() != null && MZuiAnimTools)
        {
            MZuiAnimTools.InitCurve(hideAnimCurve);
            MZuiAnimTools.UIAlpha(GetComponent<RectTransform>(), 0, hideAnimTime, () =>
            {
                OnHideAnimEnd();
            }, ZUIAnimTools.EaseType.Curve);
        }

        /*if (blockInteractOnBeginHide)
        {
            var cg = gameObject.GetComponent<CanvasGroup>();
            if (cg == null)
                cg = gameObject.AddComponent<CanvasGroup>();
            cg.interactable = false;
        }*/
    }

    protected void InitUICanvas(Canvas canvas,Camera worldCam,int screenWidth,int screenHeight)
    {
        canvas.renderMode = RenderMode.ScreenSpaceCamera;
        canvas.gameObject.layer = LayerMask.NameToLayer("UI");
        canvas.worldCamera = worldCam;// s_uiCamera;

        CanvasScaler canvasScaler = canvas.GetComponent<CanvasScaler>();
        if (canvasScaler == null)
            canvasScaler = canvas.gameObject.AddComponent<CanvasScaler>();
        canvasScaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize;
        canvasScaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight;
        canvasScaler.referenceResolution = new Vector2(screenWidth, screenHeight);
      
        canvasScaler.matchWidthOrHeight = GetScalerMatch();

        GraphicRaycaster gr = canvas.GetComponent<GraphicRaycaster>();
        if (gr == null)
            gr = canvas.gameObject.AddComponent<GraphicRaycaster>();
    }
    public static float GetScalerMatch()
    {
        //return 0.5f;
        float ratio = (float)Screen.width / Screen.height;
        float f = (1080 / 1920f) / ratio ;
        if (f > 1)
        {
            float lerp = f;
            lerp *= 1.0f;
            return  Mathf.Lerp(0.5f,0,lerp);;
        }
        else
        {
            float lerp = f;
            lerp *= 1.25f;
            return  Mathf.Lerp(0.5f,1,lerp);;
        }
    }

    protected UnityEngine.GameObject m_BlackBG;
    protected UnityEngine.GameObject CreateBackground()
    {
        var black = new UnityEngine.GameObject("black").AddComponent<Image>();
        black.transform.SetParent(transform);

        if (transform.parent != null)
            black.gameObject.layer = transform.parent.gameObject.layer;
        else
            black.gameObject.layer = LayerMask.NameToLayer("UI");

        black.transform.SetAsFirstSibling();
        black.transform.localScale = Vector3.one;
        black.rectTransform.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, 0, 0);
        black.rectTransform.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Top, 0, 0);
        black.rectTransform.anchorMin = new Vector2(0, 0);
        black.rectTransform.anchorMax = new Vector2(1, 1);

        var rect = black.GetComponent<RectTransform>();
        var pos = rect.anchoredPosition3D;
        pos.z = 10;
        rect.anchoredPosition3D = pos;

        black.color = new Color(0, 0, 0, backgroundAlpha);

        return black.gameObject;
    }
    
    public static Camera NewUICamera(int screenWidth, int screenHeight,int depth,int layerMask, string name)
    {
        Camera camera = null;
         
        var pref = Resources.Load<Camera>("Scene/Common/UICamera");
        if (pref)
        {
            camera = Instantiate(pref);
        }
        else
        {
            camera = new UnityEngine.GameObject(name).AddComponent<Camera>();
            camera.orthographic = true;
            camera.orthographicSize = screenHeight / 2;
            camera.transform.position = new Vector3(screenWidth / 2, screenHeight / 2, 10);
            camera.transform.rotation = Quaternion.Euler(new Vector3(0, 0, 0));
            camera.backgroundColor = Color.black;
            camera.depth = depth;
            camera.clearFlags = CameraClearFlags.Depth;
            camera.cullingMask = layerMask;
        }
        camera.name = name;
        //UniversalAdditionalCameraData cameraData = Camera.main.GetUniversalAdditionalCameraData();
        //cameraData.cameraStack.Add(camera);
        return camera;
    }

    public static Camera NewDefaultUICam()
    {
        return  NewUICamera(defaultUIWidth, defaultUIHeight, uiCameraLayer, 1 << LayerMask.NameToLayer("UI"), "UICamera");
    }

    public static Camera NewDefaultUIFXCam()
    {
        return NewUICamera(defaultUIWidth, defaultUIHeight, uiFXCameraLayer, 1 << LayerMask.NameToLayer("TransparentFX"), "UIFXCamera");
    }


    protected bool showAnimEnded;
    /// <summary>
    /// 淡入动画播放完
    /// </summary>
    protected virtual void OnShowAnimEnd()
    {
        showAnimEnded = true;
    }
    /// <summary>
    /// 淡出动画播放完
    /// </summary>
    protected virtual void OnHideAnimEnd()
    {
        
    }

/// <summary>
/// 加载到界面
/// </summary>
    protected virtual void GoBackToView()
    {

    }

    Text m_BlockEventUI;
    /// <summary>
    /// 屏蔽点击事件
    /// </summary>
    public void BlockInteract()
    {
        if (m_BlockEventUI == null)
        {
            m_BlockEventUI = new UnityEngine.GameObject("Block").AddComponent<Text>();
            m_BlockEventUI.transform.SetAsLastSibling();
            SetUIStretchAll(m_BlockEventUI.GetComponent<RectTransform>());
        }
    }
    /// <summary>
    /// 打开点击事件
    /// </summary>
    public void ReleaseBlock()
    {
        if(m_BlockEventUI)
        {
            Destroy(m_BlockEventUI.gameObject);
        }
    }

    public void GoBack()
    {
        if (showAnimEnded)
        {
            GoBackToView();
        }
        //m_Controller.RemoveFromNav();
    }

    protected ViewController m_Controller;
    public void SetViewController(ViewController controller)
    {
        m_Controller = controller;

        if(m_Controller.parentNav)
            layer = m_Controller.parentNav.GetIndex(m_Controller);
    }

    protected void OnDisable()
    {
        if (m_SecondUICanvas != null)
          m_SecondUICanvas.gameObject.SetActive(false);
    }

    protected virtual void OnDestroy()
    {
        if (secondLayerUICam != null)
        {
            secondLayerUICam.enabled = false;
            Destroy(secondLayerUICam.gameObject);
        }
        secondLayerUICam = null;

        if (m_SecondUICanvas != null)
            Destroy(m_SecondUICanvas.gameObject);

        m_SecondUICanvas = null;
    }

    public static void SetUIStretchAll(RectTransform rt)
    {
        rt.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Left, 0, 0);
        rt.SetInsetAndSizeFromParentEdge(RectTransform.Edge.Top, 0, 0);
        rt.anchorMin = new Vector2(0, 0);
        rt.anchorMax = new Vector2(1, 1);
    }

#if UNITY_EDITOR
    private int m_PreScreenHeight;
    protected virtual void LateUpdate()
    {
        if (m_PreScreenHeight != Screen.height)
        {
            GameDebug.Log("更换分辨率");
            m_PreScreenHeight = Screen.height;
            CanvasScaler canvasScaler = GetComponent<CanvasScaler>();
            if (canvasScaler)
            {
                canvasScaler.matchWidthOrHeight = GetScalerMatch();
            }
        }
    }
#endif
}
